package com.csx.governance.traffic.adapter.config;

import com.csx.governance.traffic.adapter.outbound.LoadBalancerInstanceSupplierBeanPostProcessor;
import com.csx.governance.traffic.adapter.outbound.webclient.TrafficLoadBalancerLifecycle;
import com.csx.governance.traffic.adapter.outbound.webclient.TrafficReactorLoadBalancerAspect;
import com.csx.governance.traffic.core.interceptor.TrafficHandlerInterceptorRunner;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;

/**
 * <p> Spring Cloud LoadBalancer 的配置类</p>
 * @author cuisongxu
 * @date 2023/4/9 20:23
 */
@Configuration
@ConditionalOnClass(name = "org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier")
public class TrafficLoadBalancerConfiguration {

    @Bean
    public LoadBalancerInstanceSupplierBeanPostProcessor loadBalancerInstanceSupplierBeanPostProcessor() {
        return new LoadBalancerInstanceSupplierBeanPostProcessor();
    }

    @Bean
    public TrafficLoadBalancerLifecycle trafficLoadBalancerLifecycle(ApplicationContext applicationContext,
                                                                     @Qualifier("outboundHandlerInterceptorRunner") TrafficHandlerInterceptorRunner handlerInterceptorRunner){
        return new TrafficLoadBalancerLifecycle((GenericApplicationContext) applicationContext, handlerInterceptorRunner);
    }

    @Bean
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
    public TrafficReactorLoadBalancerAspect trafficReactorLoadBalancerAspect(ApplicationContext applicationContext) {
        return new TrafficReactorLoadBalancerAspect((GenericApplicationContext) applicationContext);
    }
}
